package jp.co.nes.awssupport.business.utility;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import jp.co.nes.awssupport.common.bean.AppInfoBean;
import jp.co.nes.awssupport.common.utility.AppInfoUtil;

/**
 * ボリューミングプランヘルパーです。
 */
public class VolumingPlanHelper {

    /** マージ後の製品名 */
    // 本プロダクト名は、請求CSVファイルや日次集計一時処理用などのデータには入ってこない
    // また、このプロダクト名は常にボリューミングプラン適用でよい。
    public static final String MERGE_PRODUCT_NAME = "AWS Data Transfer";

    /** マージする製品の使用タイプのサフィックス */
    public static final String MERGE_USAGE_TYPE_SUFFIX = "DataTransfer-Out-Bytes";

    /** アプリケーション情報に設定されているボリューミングプラン情報リスト */
    private List<String[]> planList;

    /**
     * デフォルトコンストラクタです。
     */
    public VolumingPlanHelper() {
        planList = getPlanList();
    }

    /**
     * ボリューミングプランを適用する製品名・使用タイプかを判断します。
     *
     * @param productName 製品名
     * @param usageType 使用タイプ
     * @return true: 適用します, false: 適用しません
     */
    public boolean isApply(String productName, String usageType) {
        return planList.stream().anyMatch(v -> {
            if (Boolean.parseBoolean(v[3])) {
                if (productName != null && productName.equals(v[0]) && usageType != null && usageType.endsWith(v[1])) {
                    return true;
                }
            } else {
                if (productName != null && productName.equals(v[0]) && usageType != null && usageType.equals(v[1])) {
                    return true;
                }
            }
            return false;
        });
    }

    /**
     * ボリューミングプランを適用する製品名・使用タイプから、使用タイプサフィックスを返却します。
     *
     * @param productName 製品名
     * @param usageType 使用タイプ
     * @return 使用タイプサフィックス
     */
    public String getUsageTypeSuffix(String productName, String usageType) {
        if (!isApply(productName, usageType)) {
            return null;
        }

        String result = null;
        for (String[] v : planList) {
            if (Boolean.parseBoolean(v[3])) {
                if (productName != null && productName.equals(v[0]) && usageType != null && usageType.endsWith(v[1])) {
                    result = v[1];
                    break;
                }
            } else {
                if (productName != null && productName.equals(v[0]) && usageType != null && usageType.equals(v[1])) {
                    result = v[1];
                    break;
                }
            }
        }
        return result;
    }

    /**
     * ボリューミングプランを適用する製品名・使用タイプから、リージョンコード付加を返却します。
     *
     * @param productName 製品名
     * @param usageType 使用タイプ
     * @return true: リージョンコード追加付加します, false: リージョンコード追加付加しません
     */
    public boolean isRegionCodeAddition(String productName, String usageType) {
        if (!isApply(productName, usageType)) {
            return true;
        }

        String isRegionCodeAdditionValue = null;
        for (String[] v : planList) {
            if (Boolean.parseBoolean(v[3])) {
                if (productName != null && productName.equals(v[0]) && usageType != null && usageType.endsWith(v[1])) {
                    isRegionCodeAdditionValue = v[2];
                    break;
                }
            } else {
                if (productName != null && productName.equals(v[0]) && usageType != null && usageType.equals(v[1])) {
                    isRegionCodeAdditionValue = v[2];
                    break;
                }
            }
        }
        return (isRegionCodeAdditionValue == null ? true : Boolean.parseBoolean(isRegionCodeAdditionValue));
    }

    /**
     * アプリケーション情報に設定されているボリューミングプラン情報リストを返却します。
     *
     * @return ボリューミングプラン情報リスト
     */
    private List<String[]> getPlanList() {
        List<String[]> planList = new ArrayList<>();
        List<AppInfoBean> appInfoList = AppInfoUtil.getList("VolumingPlan");
        for (AppInfoBean appInfoBean : appInfoList) {
            Map<String, String> info = appInfoBean.getInfo();
            if (info != null) {
                String[] values = new String[4];
                values[0] = info.get("ProductName");
                values[1] = info.get("UsageTypeSuffix");
                values[2] = info.get("RegionCodeAddition");
                values[3] = info.get("BackwardPartialMatch");
                planList.add(values);
            }
        }
        return planList;
    }
}
